package com.smedi.ismedi.authoritymanagement.core.application.query.impl;

import com.smedi.ismedi.authoritymanagement.core.application.query.FrameStructureQueryService;
import com.smedi.ismedi.authoritymanagement.core.application.query.vo.FrameStructureVo;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.FrameStructure;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RolePermissionDetail;
import com.smedi.ismedi.authoritymanagement.core.domain.service.FrameStructureDomainService;
import com.smedi.ismedi.authoritymanagement.core.domain.service.RoleBasicDomainService;
import com.smedi.ismedi.authoritymanagement.core.domain.service.RolePermissionDetailDomainService;
import com.smedi.ismedi.authoritymanagement.core.domain.service.TermDomainService;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @Author: xulinjun
 * @Date: 2021-7-23 17:07
 */
@Slf4j
@Service
@AllArgsConstructor
public class FrameStructureQueryServiceImpl implements FrameStructureQueryService {
    private static final String routerPath = "routerPath";

    private final DozerUtil dozerUtil;

    private final FrameStructureDomainService frameStructureDomainService;

    private final TermDomainService termDomainService;

    private final RoleBasicDomainService roleBasicDomainService;

    private final RolePermissionDetailDomainService rolePermissionDetailDomainService;

    /**
     * 获取结构下的路由
     *
     * @param frameStructure
     * @param termTypes
     * @return
     */
    private List<String> getFrameStructureRouters(FrameStructure frameStructure, List<String> termTypes) {
        List<String> routers = new ArrayList<>();
        if (!frameStructure.isRoot()) {
            // 是否允许下坠
            boolean isAllow = true;
            if (termTypes.size() > 0) {
                isAllow = termTypes.contains(frameStructure.getType());
            }

            if (isAllow) {
                Object attribute = termDomainService.getAttribute(frameStructure.getType(), frameStructure.getTermId(), routerPath);
                if (attribute != null) {
                    routers.add(String.valueOf(attribute));
                }

                // 只有父节点允许，才会去取子节点
                List<FrameStructure> children = frameStructureDomainService.queryChildren(frameStructure.getStructureId());
                for (FrameStructure child : children) {
                    List<String> childRouters = getFrameStructureRouters(child, termTypes);
                    if (childRouters.size() > 0) {
                        routers.addAll(childRouters);
                    }
                }
            } else {
                return routers;
            }
        } else {
            List<FrameStructure> children = frameStructureDomainService.queryChildren(frameStructure.getStructureId());
            for (FrameStructure child : children) {
                List<String> childRouters = getFrameStructureRouters(child, termTypes);
                if (childRouters.size() > 0) {
                    routers.addAll(childRouters);
                }
            }
        }

        return routers;
    }

    /**
     * 获取结构下的信息
     *
     * @param frameStructure
     * @param termTypes
     * @param rolePermissionDetails
     * @return
     */
    private FrameStructureVo generateFrameStructureTree(FrameStructure frameStructure, List<String> termTypes, List<RolePermissionDetail> rolePermissionDetails) {
        // 添加标识角色勾选的标记
        Optional<RolePermissionDetail> optional = rolePermissionDetails.stream().filter(rolePermissionDetail -> rolePermissionDetail.getStructureId().equals(frameStructure.getStructureId())).findAny();
        if (optional.isPresent()) {
            frameStructure.setCheckedAllChildren(optional.get().isAllChildren())
                    .setCheckedByThisRole(true);
        }

        if (!frameStructure.isRoot()) {
            // 是否允许下坠
            boolean isAllow = true;
            if (termTypes.size() > 0) {
                isAllow = termTypes.contains(frameStructure.getType());
            }

            if (isAllow) {
                frameStructure.setTerm(termDomainService.queryTermByTermIdAndType(frameStructure.getTermId(), frameStructure.getType()));
                // 只有父节点允许，才会去取子节点
                List<FrameStructure> children = frameStructureDomainService.queryChildren(frameStructure.getStructureId());
                for (FrameStructure child : children) {
                    FrameStructureVo childVo = generateFrameStructureTree(child, termTypes, rolePermissionDetails);
                    if (childVo != null) {
                        frameStructure.getChildren().add(childVo);
                    }
                }
            } else {
                return null;
            }
        } else {
            List<FrameStructure> children = frameStructureDomainService.queryChildren(frameStructure.getStructureId());
            for (FrameStructure child : children) {
                FrameStructureVo childVo = generateFrameStructureTree(child, termTypes, rolePermissionDetails);
                if (childVo != null) {
                    frameStructure.getChildren().add(childVo);
                }
            }
        }

        return dozerUtil.mapGeneric(frameStructure, FrameStructureVo.class);
    }

    @Override
    public FrameStructureVo queryFrameStructureByRootCode(String rootCode, List<String> termTypes, Long roleId) {
        if (roleId != null) {
            roleBasicDomainService.getRoleBasicByRoleId(roleId); // 判断当前roleId是否存在真实数据
        }

        // 获取当前角色对应的已选择的功能组权限
        List<RolePermissionDetail> rolePermissionDetails = StringUtils.isEmpty(roleId)
                ? Collections.unmodifiableList(new ArrayList<>())
                : rolePermissionDetailDomainService.getRolePermissionDetailsByRootCodeAndRoleId(rootCode, roleId);

        // 获取根节点
        FrameStructure frameStructure = frameStructureDomainService.queryFrameStructureByRootCode(rootCode);

        return generateFrameStructureTree(frameStructure, termTypes, rolePermissionDetails);
    }

    @Override
    public List<String> queryFrameStructureRoutersByRootCode(String rootCode, List<String> termTypes) {
        FrameStructure frameStructure = frameStructureDomainService.queryFrameStructureByRootCode(rootCode);
        return getFrameStructureRouters(frameStructure, termTypes);
    }
}
